package com.comp490.sprite;

import java.util.ArrayList;

import android.graphics.Canvas;
import android.graphics.Rect;

import com.comp490.pattern.BulletPattern;
import com.comp490.shooter.GameView;
import com.comp490.sound.SoundManager;

public abstract class EnemySprite extends Sprite implements Ship
{
    public static float PI = 3.1415927410125732421875f;
    public static final int MOVE_STRAIGHT = 0;
    public static final int MOVE_SIN = 1;

    protected int spriteLeft;
    protected int spriteTop;
    protected int fCount;
    protected int hitPoints;
    protected int firePoint;
    protected int path;
    protected int value;
    protected float collisionRadius;
    protected boolean active;
    protected ExplosionSprite mExplosionSprite;
    protected ArrayList<BulletPattern> bulletPatterns;
    protected boolean shipIsHit;
    protected Rect src, dst;

    public EnemySprite(GameView gameView, int hp, int val)
    {
        super(gameView);
        mExplosionSprite = new ExplosionSprite(gameView);
        spriteLeft = spriteTop = fCount = firePoint = 0;
        hitPoints = hp;
        value = val;
        active = true;
        shipIsHit = false;
        bulletPatterns = new ArrayList<BulletPattern>(5);
    }

    public static float toRadians(float degrees)
    {
        return degrees * PI / 180;
    }

    public float collisionRadius()
    {
        return collisionRadius;
    }

    public void hit(int damage)
    {
        if(explode)
            return;

        hitPoints -= damage;
       	shipIsHit = true;
        
       	if(hitPoints < 1)
        {
        	if(this instanceof LargeEnemySprite)
        		SoundManager.playSoundEfx(SoundManager.BIG_ENEMY_EXPLOSION);
        	else
        		SoundManager.playSoundEfx(SoundManager.ENEMY_EXPLOSION);
            gameView.updateScore(value);
            explode = true;
            active = false;
        }
    }

    public int getBitmapHeight()
    {
        return bmpHeight;
    }

    public int getBitmapWidth()
    {
        return bmpWidth;
    }

    /**
     * Moves object in a straight line based on input parameters.
     * 
     * @param delta
     *            total displacement in number of pixels
     * @param theta
     *            angle of displacement in degrees (the y-axis is inverted so
     *            the angle will grow clockwise)
     */
    public void moveLine(float delta, float theta)
    {
        x += delta * android.util.FloatMath.cos(toRadians(theta));
        y += delta * android.util.FloatMath.sin(toRadians(theta));
    }

    /**
     * Moves object in a sinusoidal motion.
     * 
     * @param amplitude
     *            adjusts the movement in the y direction (number of pixels to
     *            displace each function call)
     * @param period
     *            adjusts the movement in the x direction (more specifically it
     *            specifies the number of pixels in which a full revolution is
     *            drawn)
     */
    public void moveSin(float amplitude, float period)
    {
        y += amplitude * android.util.FloatMath.sin(toRadians(x));
        x -= toRadians(period);
    }
    
    public void collisionCheck(ShipSprite playerShip)
    {
    	if(!playerShip.isActive())
    		return;
    	
		float dx = getCenterBitmapX() - playerShip.getCenterBitmapX();
		float dy = getCenterBitmapY()- playerShip.getCenterBitmapY();
		if(android.util.FloatMath.sqrt(dx * dx + dy * dy) < collisionRadius + playerShip
				.collisionRadius())
		{
			hit(playerShip.getHealth());
			playerShip.hit(100);
		}
    }
    
    public boolean isActive()
	{
		return active;
	}

	public void setActive(boolean active)
	{
		this.active = active;
	}

    protected boolean boundsCheck(GameView g)
    {
        return x > -bmpWidth;
    }

	public abstract void updatePosition();

    public abstract void draw(Canvas canvas);

    public abstract void reset();

    protected abstract void checkFirePos();

    protected abstract void buildBulletPatterns();
}